﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace B10_Ex02_Elad_034695114_Meyron_026607788
{
    using Infrastructure.ObjectModel;
    using Infrastructure.ServiceInterfaces;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Graphics;
    using Infrastructure.Managers;
    using B10_Ex02_Elad_034695114_Meyron_026607788;
    using B10_Ex02_Elad_034695114_Meyron_026607788.ObjectModel;

    public class SpaceShip : Sprite
    {
        #region Consts and members
        private const string k_AssteName = @"Sprites\Ship01_32x32";
        private const float k_Velocity = 80f;
        private const float k_MaxBullets = 2;
        private const float k_BulletVelocity = 200f;
        private IInputManager m_InputManager;
        private List<Sprite> m_Bullets;
        #endregion

        public List<Sprite> Bullets
        {
            get
            {
                return m_Bullets;
            }

            protected set
            {
                m_Bullets = value;
            }
        }

        #region CTor and Init
        /// <summary>
        /// Initilizes a new instance of spaceship
        /// </summary>
        /// <param name="i_Game">The owenr</param>
        public SpaceShip(Game i_Game)
            : base(k_AssteName, i_Game)
        {
            // Register to game components
            this.Game.Components.Add(this);
            Bullets = new List<Sprite>();
        }

        /// <summary>
        /// Sets init stuff
        /// </summary>
        public override void Initialize()
        {
            // Uses a lot of input manager
            m_InputManager = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
            base.Initialize();
        } 
        #endregion

        #region Other Methods
        /// <summary>
        /// Sets the bounds of the space shop
        /// </summary>
        protected override void InitBounds()
        {
            base.InitBounds();

            // put in bottom right of view port:
            // get the bottom and right
            float x = (float)GraphicsDevice.Viewport.Width - (Width * 2);
            float y = (float)GraphicsDevice.Viewport.Height;

            // offset:
            x -= m_Width / 2;
            y -= m_Height / 2;

            // put it a little bit higher:
            y -= 30;

            // Set the new position
            this.Position = new Vector2(x, y);
        }

        /// <summary>
        /// Occours all the time
        /// </summary>
        /// <param name="gameTime">The time passed</param>
        public override void Update(GameTime gameTime)
        {
            // Look if we are moving
            checkMovement();

            // Check if we were out of bounds
            this.Position = new Vector2(
                            MathHelper.Clamp(
                            this.Position.X, 
                            1,
                            Game.GraphicsDevice.Viewport.Width - this.Width - 1),
                            this.Position.Y);

            this.handleBullets();

            // Called anyways
            base.Update(gameTime);
        }

        private void checkMovement()
        {
            // Check if the spaceship is moving left
            if (m_InputManager.KeyboardState.IsKeyDown(Keys.Left) || (m_InputManager.MousePositionDelta.X < 0))
            {
                // Set the speed to left
                m_Velocity.X = k_Velocity * -1;
            }
            else if (m_InputManager.KeyboardState.IsKeyDown(Keys.Right) || (m_InputManager.MousePositionDelta.X > 0))
            {
                // Set the speed to right
                m_Velocity.X = k_Velocity;
            }
            else
            {
                // Set to zero
                m_Velocity.X = 0;
            }
        }

        /// <summary>
        /// Fires a bullet to the top
        /// </summary>
        protected void handleBullets()
        {
            // Check for passed Bullets and removes them from the collection
            for (int nBulletIndex = 0; nBulletIndex < this.Bullets.Count; nBulletIndex++)
            {
                if (!this.Bullets[nBulletIndex].Enabled)
                {
                    this.Bullets.RemoveAt(nBulletIndex);
                    nBulletIndex--;
                }
            }

            // Check if the player fired
            if (m_InputManager.KeyPressed(Keys.Enter) || m_InputManager.ButtonPressed(eInputButtons.Left))
            {
                // Check if the player is allowed to fire another bullet (checks all enabled bullets)
                if (this.Bullets.FindAll(bullet => bullet.Enabled == true).Count < k_MaxBullets)
                {
                    // Create and fire a bullet using the spaceship location
                    Bullets.Add(new PlayerBullet(
                       (Invadors)this.Game,
                       new Vector2(Position.X + (m_Width / 2), Position.Y - (this.Height / 2))));
                }
            }
        } 
        #endregion
    }
}